package cc.eddic.pratice.programmingparadigms.nginxlog.impl;

import cc.eddic.pratice.programmingparadigms.nginxlog.LogItem;
import cc.eddic.pratice.programmingparadigms.nginxlog.LogReport;
import cc.eddic.pratice.programmingparadigms.nginxlog.NginxLogItem;
import cc.eddic.pratice.programmingparadigms.nginxlog.PageViewsAndUniqueVisitors;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

public class LogReportCxyImpl implements LogReport {

    //返回PageViewsAndUniqueVisitors
    @Override
    public PageViewsAndUniqueVisitors pageViewsAndUniqueVisitors(List<NginxLogItem> items) {

        long pageViews = items.size();

        Map<String, Long> uniqueVisitorsMap = items.stream()
                .collect(Collectors.groupingBy(user -> user.getIp() +
                        "-" + user.getUserAgent(), Collectors.counting()));

        long uniqueVisitors = uniqueVisitorsMap.values().size();

        return new PageViewsAndUniqueVisitors(pageViews, uniqueVisitors);

    }


    //根据path返回PathModel
    public PathModel pageViewsAndUniqueVisitors(String path, List<LogItem> items) {
        long pv = items.size();
        long uv = items.stream().collect(Collectors.groupingBy(
                item -> item.getIp() + item.getUserAgent()
        )).size();
        return new PathModel(path, pv, uv);
    }


    //截取小时
    public static int extractHour(String dateTimeString) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z", Locale.ENGLISH);
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeString, formatter);

        return zonedDateTime.getHour();

    }


    @Override
    public Map<Integer, PageViewsAndUniqueVisitors> pageViewsAndUniqueVisitorsByHour(List<NginxLogItem> items) {

        return items.stream()
                .collect(Collectors.groupingBy(x -> extractHour(x.getTime())))
                .entrySet().stream().map(entry -> new AbstractMap.SimpleEntry<>(
                        entry.getKey(),
                        pageViewsAndUniqueVisitors(entry.getValue())
                )).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    }


    @Override
    public List<PathModel> pageViewsAndUniqueVisitorsByPath(List<LogItem> items) {

        Comparator<PathModel> reversedComparator = (a, b) -> Long.compare(b.getPv(), a.getPv());

        return items.stream()
                .collect(Collectors.groupingBy(LogItem::getPath))
                .entrySet().stream()
                .map(entry -> pageViewsAndUniqueVisitors(entry.getKey(), entry.getValue()))
                .sorted(reversedComparator)
                .collect(Collectors.toList());

    }


}


